package standalone;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;

public class MPQAConverter {

	public static void main(String[] args) throws IOException {
		new MPQAConverter();
	}

	// overall-strength {high, medium, low}
	// intensity {low, medium, high, extreme}
	// expression-intensity {neutral, low, medium, high, extreme}
	// positive-intensity {low, medium, high, extreme}

	// es-uncertain {somewhat-uncertain, very-uncertain}

	// polarity {both, negative, neutral, positive, res, uncertain-both,
	// uncertain-negative, uncertain-neutral, uncertain-positive}

	// attitude-type {agree-neg, agree-pos, arguing-neg, arguing-pos,
	// intention-neg, intention-pos, other, other-attitude, sentiment-neg,
	// sentiment-pos, specilation, speculation}

	// other: sarcastic {yes}

	// returns, neg, pos, neu
	private String emotions(String key, String value) {
		if (key.equals("polarity")) {
			if (value.contains("positive"))
				return "pos";
			if (value.contains("negative"))
				return "neg";
			if (value.contains("neutral") || value.contains("both"))
				return "neu";
		}
		// if (value.contains("sentiment-neg"))
		// return "neg";
		// if (value.contains("sentiment-pos"))
		// return "pos";
		// if (value.contains("intention-neg"))
		// return "neg";
		// if (value.contains("intention-pos"))
		// return "pos";
		return null;
	}

	public MPQAConverter() throws IOException {
		String path = "C:\\Users\\rsg\\Documents\\corpus\\sentence polarity corpus\\database.mpqa.2.0\\";
		BufferedWriter out = new BufferedWriter(new FileWriter("news.txt"));
		File[] parentDocs = new File(path + "docs").listFiles();
		Map<String, String> corpus = new HashMap<String, String>();

		int filesRead = 0;
		for (File parentDoc : parentDocs) {
			if (exclude(parentDoc))
				continue;
			for (File doc : parentDoc.listFiles()) {
				filesRead++;
				String docPath = doc.getAbsolutePath();
				File anns = new File(docPath.replaceAll("docs", "man_anns")
						+ "\\gateman.mpqa.lre.2.0");
				if (filesRead % 10 == 0)
					System.out.println(filesRead + " documents read.");

				HashMap<Span, String[]> annotations = findAnnotations(anns);
				HashMap<Span, String> text = findText(annotations.keySet(), doc);

				for (Entry<Span, String[]> s : annotations.entrySet()) {
					String emotion = emotions(s.getValue()[0], s.getValue()[1]);
					if (emotion == null)
						continue;
					String str = text.get(s.getKey());
					str = str.replaceAll("\n+", " ");
					str = str.trim();
					if (corpus.containsKey(str)) {
						if (corpus.get(str).equals("both"))
							continue;
						if (!corpus.get(str).equals(emotion))
							corpus.put(str, "both");
					} else
						corpus.put(str, emotion);
					// System.out.println(emotion + "\t" + str);
				}

			}
		}
		for (Entry<String, String> e : corpus.entrySet()) {
			String emotion = e.getValue();
			if (emotion.equals("objective") || emotion.equals("both"))
				emotion = "neu";
			String str = e.getKey();
			if (!(str.contains(",") || str.contains(".") || str.contains("!")
					|| str.contains("?") || str.contains(" ")))
				// Small fragment
				continue;
			if (str.matches(".*[^.,!?]$"))
				str += ".";
			out.append(emotion + "\t" + str + "\n");
		}
		out.flush();
		out.close();
	}

	private HashMap<Span, String> findText(Set<Span> keySet, File doc)
			throws IOException {
		BufferedReader docbr = new BufferedReader(new FileReader(doc));
		HashMap<Span, String> sentences = new HashMap<Span, String>();

		StringBuilder str = new StringBuilder();
		while (docbr != null) {
			String line = docbr.readLine();
			if (line == null)
				break;
			str.append(line + "\n");
		}
		docbr.close();
		String document = str.toString();

		for (Span span : keySet)
			sentences.put(span, document.substring(span.start, span.end));

		return sentences;
	}

	private HashMap<Span, String[]> findAnnotations(File anns)
			throws IOException {
		BufferedReader annsbr = new BufferedReader(new FileReader(anns));
		HashMap<Span, String[]> split = new HashMap<Span, String[]>();

		int index = 0;

		while (annsbr != null) {
			String line = annsbr.readLine();
			if (line == null)
				break;
			if (line.trim().startsWith("#"))
				continue;
			Scanner scr = new Scanner(line);
			scr.useDelimiter("\t|,");
			scr.nextInt(); // discard index
			int startPos = scr.nextInt();
			int endPos = scr.nextInt();
			scr.next(); // string
			scr.next(); // type
			if (scr.hasNext()) {
				String sent = scr.nextLine();
				sent = sent.replaceAll(", ", ",");
				sent = sent.replaceAll("\t", " ").trim();
				if (sent.isEmpty())
					continue;

				String[] keys = sent.replaceAll("=\"[a-zA-Z0-9., -]*\"", "")
						.split(" ");
				String[] values = sent.replaceAll(
						"[a-z-]+=\"([a-zA-Z0-9., -]*)\"", "$1").split(" ");

				for (int i = 0; i < keys.length; i++) {
					String key = keys[i];
					String[] value = values[i].split(",");
					String[] entry = new String[value.length + 1];
					entry[0] = key;
					for (int j = 1; j < entry.length; j++)
						entry[j] = value[j - 1];
					split.put(new Span(startPos, endPos, index++), entry);
				}
			}
		}
		return split;
	}

	private boolean exclude(File parent) throws IOException {
		return (parent.getCanonicalPath().contains("non_fbis"))
				|| (parent.getCanonicalPath().contains("temp_fbis"))
				|| (parent.getCanonicalPath().contains("ula"))
				|| (parent.getCanonicalPath().contains("xbank"));
	}

	private class Span {
		private int start;
		private int end;
		private int index;

		public Span(int start, int end, int index) {
			this.start = start;
			this.end = end;
			this.index = index;
		}

		@Override
		public int hashCode() {
			return index;
		}

		@Override
		public boolean equals(Object o) {
			Span s = (Span) o;
			return start == s.start && end == s.end && index == s.index;
		}

		@Override
		public String toString() {
			return start + "," + end;
		}
	}
}
